//
// hash.h
// libprotea
// Tools Library for the Protea Project / Hash algorithms
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
// 
// theproteaproject@gmail.com
//

#ifndef __PROTEA_HASH_H__
#define __PROTEA_HASH_H__

typedef unsigned int word32;
typedef unsigned char byte;


// CRC32
class __EXPORT XCcrc32 : public XCBase
{
public:
	XCcrc32();
	word32	Get_CRC32( byte* data, long len );
	word32	Get_Checksum( byte* data, long len );

private:
	word32	Reflect( word32 ref, char ch );

	word32	crc32_table[ 256 ];
};


// Generic hash class
class XCHashClass : public XCBase {
public:
	XCHashClass();
	~XCHashClass();

	virtual void Init();
	virtual void Update( const unsigned char* stream, int len );
	virtual const void* Final();

	virtual int GetDigestSize() = 0;

	HASH_HANDLE hHash;

protected:
	virtual void Transform( word32* buffer, const word32* input ) = 0;

	bool little_endian;
	long block_size;
	word32* input;			// Input buffer
	word32* digest;			// Digest work area
	word32 bytes[2];		// 64 bit byte length

	word32 GetCountHi() { return bytes[1] << 3 | bytes[0] >> 29; };
	word32 GetCountLo() { return bytes[0] << 3; };
};



// MD5
class XCMD5Hash : public XCHashClass {
public:
	void Init();
	int GetDigestSize();

private:
	void Transform( word32* buf, const word32* data );
};



// SHA-1
class XCSHAHash : public XCHashClass {
public:
	void Init();

	XCSHAHash();
	~XCSHAHash();

	SHA_UPDATE
	SHA_FINAL

	int GetDigestSize();

private:
	void Transform( word32 *state, const word32 *data );
};




bool XCValidateSignature( XCHashClass* hash, char* existing_signature, int sig_len );


#endif
